package team.nmsg.ge.system.dao;

import java.beans.PropertyDescriptor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.math.BigInteger;
import java.util.List;

import org.hibernate.transform.ResultTransformer;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * 20160902 Guodeqi 自定义的数据库字库转换成POJO 
 * 将 hibernate 查询结果集转化成对应java 对象
 */
public class SysRsTransformer implements ResultTransformer {

	private static final Logger logger = LoggerFactory.getLogger (SysRsTransformer.class);

	private final Class resultClass;

	public SysRsTransformer(Class resultClass) {
		if (resultClass == null)
			throw new IllegalArgumentException("resultClass cannot be null");
		this.resultClass = resultClass;
	}

	// 结果转换时，HIBERNATE调用此方法
	public Object transformTuple(Object[] tuple, String[] aliases) {
		Object result = null;
		try {
			result = resultClass.newInstance();
			int colLength = tuple.length;
			Field tmpField = null;
			for (int i = 0; i < colLength; i++) {
				Object srcValue = tuple[i];
				String srcColName = aliases[i];
				try {
					// 1 获取 Field 对应的 setter
					tmpField = getFieldByAliase(srcColName);
					if (tmpField == null) {
						continue;
					}
					String fieldname = tmpField.getName();
					
					int modifiers = tmpField.getModifiers();//静态 或 final 不遍历
					if( Modifier.isStatic(modifiers)  || Modifier.isFinal(modifiers) ){
						continue;
					}
					
					PropertyDescriptor pd = new PropertyDescriptor(fieldname, resultClass);
					Method setter = pd.getWriteMethod();
					
					// 2赋值
					Class fieldClass = tmpField.getType();
					String fieldClassName = fieldClass.getName();
					if (srcValue instanceof BigInteger) {
						BigInteger bi = (BigInteger) srcValue;
						if ("java.lang.Integer".equals(fieldClassName) || "int".equals(fieldClassName)) {
							setter.invoke(result, bi.intValue() ) ;
						} else if ("java.lang.Long".equals(fieldClassName) || "long".equals(fieldClassName)) {
							setter.invoke(result,bi.longValue() );
						} else {
							setter.invoke(result, srcValue);
						}
					} else {
						setter.invoke(result, srcValue);
					}
				} catch (Exception e) {
					logger.error( resultClass.getSimpleName() + " [Field : " + tmpField.getName() + "]  :::"+ e.getMessage() +"...");
				}
			}
		} catch (Exception e) {
			logger.error(":::", e);
		}
		return result;
	}

	private Field getFieldByAliase(String alias) {
		
		String proName = alias.toLowerCase();
		Class tmpClass = resultClass;
		for(  ; !tmpClass.equals(Object.class) ; tmpClass = tmpClass.getSuperclass() ){
			Field[] fields = tmpClass.getDeclaredFields();
			for (Field field : fields) {
				if (field.getName().toLowerCase().equals(proName)) {
					return field;
				}
			}
		}
		return null;
	}

	@Override
	public List transformList(List arg0) {
		return arg0;
	}

}
